#! /usr/bin/env python
#coding=utf-8

import os
import codecs

from .smaps import VirtualMemroyArea
from .smaps import ProcessSmaps
from .threads import parse_threads_file

class ProcessPsParser(dict):
	def __init__(self, parts):
		self["user"] = parts[0]
		self["pid"] = int(parts[1])
		self["ppid"] = int(parts[2])
		self["name"] = parts[7]

class SystemObject(dict):
	def __init__(self, idx, obj):
		self["id"] = idx
		self["processes"] = 1
		for k in obj:
			self[k] = obj[k]

	def add_obj(self, obj):
		for k in VirtualMemroyArea.VMA_SIZE_KEYS:
			self[k] = self[k] + obj[k]

		self["processes"] = self["processes"] + 1

class ProcessMgr(object):
	def __init__(self, dir):
		self._procs = []
		self._objects = []
		self._objects_dict = {}
		ps_file = os.path.join(dir, "ps/ps-ef.txt")
		with open(ps_file) as f:
			self.__load(f, dir)

	def get_all(self):
		return self._procs

	def get_all_objects(self):
		return self._objects

	def get_object_by_name(self, name):
		if name in self._objects_dict:
			return self._objects_dict[name]
		return None

	def _merge_objects(self):
		cnt = 0
		for proc in self._procs:
			for obj in proc.get_all():
				sobj = self.get_object_by_name(obj["name"])
				if sobj:
					sobj.add_obj(obj)
					continue
				cnt = cnt + 1
				sobj = SystemObject(cnt, obj)
				self._objects.append(sobj)
				self._objects_dict[obj["name"]] = sobj

	def __load(self, f, dir):
		skip_ppids = [2] # Skip kernel process
		for line in f.readlines():
			line = line.strip()
			if "shell cat" in line:
				continue
			parts = line.split()
			if len(parts) < 8:
				continue
			if parts[0] == "UID":
				continue
			proc = ProcessPsParser(parts)
			if proc["pid"] == 2: # Skip kernel root process
				continue
			if proc["ppid"] in skip_ppids:
				#print("Skip " + proc)
				continue
			if proc["name"] == "hdcd":
				skip_ppids.append(proc["pid"])

			# Load smaps info
			smaps_file = os.path.join(dir, "pids/smaps/", "%d_smaps.txt" % proc["pid"])
			print("Loading smaps info for " + smaps_file)
			proc_with_smaps = ProcessSmaps(smaps_file)
			for k, v in proc.items():
				proc_with_smaps[k] = v

			threads_file = os.path.join(dir, "pids/threads/", "%d_threads.txt" % proc["pid"])
			proc_with_smaps["threads"] = parse_threads_file(threads_file)

			self._procs.append(proc_with_smaps)
			#print(self._procs)

		self._merge_objects()

if __name__ == "__main__":
	mgr = ProcessMgr("./5min")

	print(mgr.get_all_objects())
